﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using Microsoft.SqlServer.Dts.Runtime;
using Microsoft.SqlServer.Dts.Runtime.Wrapper;

namespace MouldingAndMillwork.SSIS
{
    public partial class SSISUtility
    {
        #region CLASS: Variables
        public class Variables
        {
            #region Reading
            public static string ReadVariableAsString(IDTSVariableDispenser100 variableDispenser, string variableName, ref bool loadErrorOccurred, ref string loadErrorMessage)
            {
                string variableValue = null;

                if (!variableDispenser.Contains(variableName))
                {
                    loadErrorOccurred = true;
                    loadErrorMessage = "'" + variableName + "' - variable not found in package.";
                }
                else
                {
                    IDTSVariables100 variables = null;
                    try
                    {
                        variableDispenser.LockOneForRead(variableName, ref variables);
                    }
                    #region catch ...
                    catch
                    {
                        loadErrorOccurred = true;
                        loadErrorMessage = "Unable to lock variable '" + variableName + "' for reading.";
                    }
                    #endregion
                    if (!loadErrorOccurred)
                    {
                        if (DtsConvert.TypeCodeFromVarType((ushort)variables[0].DataType) != TypeCode.String)
                        {
                            loadErrorOccurred = true;
                            loadErrorMessage = "The variable " + variableName + " is not a String.";
                        }
                        else if (variables.Count == 1)
                        {
                            variableValue = (string)variables[0].Value;
                        }
                        else
                        {
                            loadErrorOccurred = true;
                            loadErrorMessage = "Multiple variables matched '" + variableName + "' - unable to read.";
                        }
                    }
                }

                return variableValue;
            }
            #endregion

            #region Writing
            public static void WriteVariable(IDTSVariableDispenser100 variableDispenser, string variableName, object variableValue,
                ref bool writeErrorOccurred, ref string writeErrorMessage)
            {
                if (variableDispenser.Contains(variableName))
                {
                    IDTSVariables100 variables = null;
                    try
                    {
                        variableDispenser.LockOneForWrite(variableName, ref variables);
                    }
                    #region catch ...
                    catch
                    {
                        writeErrorOccurred = true;
                        writeErrorMessage = "Unable to lock variable '" + variableName + "' for writing.";
                    }
                    #endregion
                    if (!writeErrorOccurred)
                    {
                        if (variables.Count == 1)
                        {
                            variables[0].Value = variableValue;
                        }
                        else
                        {
                            writeErrorOccurred = true;
                            writeErrorMessage = "Multiple variables matched '" + variableName + "' - unable to write.";
                        }
                    }
                }
                else
                {
                    writeErrorOccurred = true;
                    writeErrorMessage = "Variable '" + variableName + "' does not exist.";
                }
            }
            #endregion
        }
        #endregion

        #region CLASS: VariableListConverter
        public class VariableListConverter : System.ComponentModel.StringConverter
        {
            public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
            {
                if (context == null)
                {
                    return new StandardValuesCollection(new string[1] { "null context" });
                }
                if (context.Instance == null)
                {
                    return new StandardValuesCollection(new string[1] { "null context instance" });
                }

                System.Type contextInstanceType = context.Instance.GetType();
                System.Reflection.PropertyInfo[] props = contextInstanceType.GetProperties();
                System.Reflection.PropertyInfo tashHostProperty = contextInstanceType.GetProperty("PipelineTask", typeof(Microsoft.SqlServer.Dts.Runtime.TaskHost));
                if (tashHostProperty == null)
                {
                    return new StandardValuesCollection(new string[1] { "null task host prop" });
                }
                Microsoft.SqlServer.Dts.Runtime.TaskHost taskHost = tashHostProperty.GetValue(context.Instance, null) as Microsoft.SqlServer.Dts.Runtime.TaskHost;

                System.Collections.Generic.List<string> variablesList = new System.Collections.Generic.List<string>();
                variablesList.Add("");
                foreach (Microsoft.SqlServer.Dts.Runtime.Variable var in taskHost.Variables)
                {
                    if (!var.SystemVariable)
                    {
                        variablesList.Add(var.QualifiedName);
                    }
                }

                variablesList.Sort();
                return new StandardValuesCollection(variablesList);
            }

            public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
            {
                return true;
            }

            public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
            {
                return true;
            }
        }
        #endregion
    }
}
